home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / occcont.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  19.1 KB  |  797 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #include "occimpl.h"
  13.  
  14. #ifdef AFX_OCC_SEG
  15. #pragma code_seg(AFX_OCC_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CWnd support for OLE Control containment
  27.  
  28. BOOL CWnd::CreateControl(LPCTSTR lpszClass, LPCTSTR lpszWindowName,
  29.     DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
  30.     CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
  31. {
  32.     ASSERT(lpszClass != NULL);
  33.  
  34.     CLSID clsid;
  35.     HRESULT hr = AfxGetClassIDFromString(lpszClass, &clsid);
  36.     if (FAILED(hr))
  37.         return FALSE;
  38.  
  39.     return CreateControl(clsid, lpszWindowName, dwStyle, rect, pParentWnd, nID,
  40.         pPersist, bStorage, bstrLicKey);
  41. }
  42.  
  43. BOOL CWnd::CreateControl( REFCLSID clsid, LPCTSTR lpszWindowName,
  44.    DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
  45.    CFile* pPersist, BOOL bStorage, BSTR bstrLicKey )
  46. {
  47.    CRect rect2( rect );
  48.    CPoint pt;
  49.    CSize size;
  50.  
  51.    pt = rect2.TopLeft();
  52.    size = rect2.Size();
  53.  
  54.    return( CreateControl( clsid, lpszWindowName, dwStyle, &pt, &size,
  55.       pParentWnd, nID, pPersist, bStorage, bstrLicKey ) );
  56. }
  57.  
  58. BOOL CWnd::CreateControl(REFCLSID clsid, LPCTSTR lpszWindowName, DWORD dwStyle,
  59.     const POINT* ppt, const SIZE* psize, CWnd* pParentWnd, UINT nID,
  60.    CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
  61. {
  62.     ASSERT(pParentWnd != NULL);
  63.  
  64. #ifdef _DEBUG
  65.     if (afxOccManager == NULL)
  66.     {
  67.         TRACE0("Warning: AfxEnableControlContainer has not been called yet.\n");
  68.         TRACE0(">>> You should call it in your app's InitInstance function.\n");
  69.     }
  70. #endif
  71.  
  72.     if ((pParentWnd == NULL) || !pParentWnd->InitControlContainer())
  73.         return FALSE;
  74.  
  75.     return pParentWnd->m_pCtrlCont->CreateControl(this, clsid, lpszWindowName,
  76.         dwStyle, ppt, psize, nID, pPersist, bStorage, bstrLicKey);
  77. }
  78.  
  79. BOOL CWnd::InitControlContainer()
  80. {
  81.     TRY
  82.     {
  83.         if (m_pCtrlCont == NULL)
  84.             m_pCtrlCont = afxOccManager->CreateContainer(this);
  85.     }
  86.     END_TRY
  87.  
  88.     // Mark all ancestor windows as containing OLE controls.
  89.     if (m_pCtrlCont != NULL)
  90.     {
  91.         CWnd* pWnd = this;
  92.         while ((pWnd != NULL) && !(pWnd->m_nFlags & WF_OLECTLCONTAINER))
  93.         {
  94.             pWnd->m_nFlags |= WF_OLECTLCONTAINER;
  95.             pWnd = pWnd->GetParent();
  96.             if (! (GetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE) & WS_CHILD))
  97.                 break;
  98.         }
  99.     }
  100.  
  101.     return (m_pCtrlCont != NULL);
  102. }
  103.  
  104. /////////////////////////////////////////////////////////////////////////////
  105. // COleControlContainer
  106.  
  107. BEGIN_INTERFACE_MAP(COleControlContainer, CCmdTarget)
  108.     INTERFACE_PART(COleControlContainer, IID_IOleInPlaceFrame, OleIPFrame)
  109.     INTERFACE_PART(COleControlContainer, IID_IOleContainer, OleContainer)
  110. END_INTERFACE_MAP()
  111.  
  112. BEGIN_DISPATCH_MAP(COleControlContainer, CCmdTarget)
  113. END_DISPATCH_MAP()
  114.  
  115. COleControlContainer::COleControlContainer(CWnd* pWnd) :
  116.     m_pWnd(pWnd),
  117.     m_crBack((COLORREF)-1),
  118.     m_crFore((COLORREF)-1),
  119.     m_pOleFont(NULL),
  120.     m_pSiteUIActive(NULL)
  121. {
  122. }
  123.  
  124. COleControlContainer::~COleControlContainer()
  125. {
  126.     HWND hWnd;
  127.     COleControlSite* pSite;
  128.     POSITION pos = m_siteMap.GetStartPosition();
  129.     while (pos != NULL)
  130.     {
  131.         m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  132.         if (WCE_IF(TRUE,!(pSite->m_pDataSourceControl)))
  133.         {
  134.             m_siteMap.RemoveKey((void*&)hWnd);
  135.             delete pSite;
  136.         }
  137.     }
  138.  
  139.     pos = m_siteMap.GetStartPosition();
  140.     while (pos != NULL)
  141.     {
  142.         m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  143.         delete pSite;
  144.     }
  145.     m_siteMap.RemoveAll();
  146.  
  147.     RELEASE(m_pOleFont);
  148. }
  149.  
  150. BOOL COleControlContainer::CreateControl( CWnd* pWndCtrl, REFCLSID clsid,
  151.     LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, UINT nID,
  152.     CFile* pPersist, BOOL bStorage, BSTR bstrLicKey,
  153.     COleControlSite** ppNewSite )
  154. {
  155.    CRect rect2( rect );
  156.    CPoint pt;
  157.    CSize size;
  158.  
  159.    pt = rect2.TopLeft();
  160.    size = rect2.Size();
  161.  
  162.    return( CreateControl( pWndCtrl, clsid, lpszWindowName, dwStyle, &pt, &size,
  163.       nID, pPersist, bStorage, bstrLicKey, ppNewSite ) );
  164. }
  165.  
  166. BOOL COleControlContainer::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
  167.     LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
  168.    UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey,
  169.    COleControlSite** ppNewSite)
  170. {
  171.     COleControlSite* pSite = NULL;
  172.  
  173.     TRY
  174.     {
  175.         pSite = afxOccManager->CreateSite(this);
  176.     }
  177.     END_TRY
  178.  
  179.     if (pSite == NULL)
  180.         return FALSE;
  181.  
  182.     BOOL bCreated = SUCCEEDED( pSite->CreateControl(pWndCtrl, clsid,
  183.         lpszWindowName, dwStyle, ppt, psize, nID, pPersist, bStorage,
  184.       bstrLicKey ) );
  185.  
  186.     if (bCreated)
  187.     {
  188.         ASSERT(pSite->m_hWnd != NULL);
  189.         m_siteMap.SetAt(pSite->m_hWnd, pSite);
  190.         if (ppNewSite != NULL)
  191.             *ppNewSite = pSite;
  192.     }
  193.     else
  194.     {
  195.         delete pSite;
  196.     }
  197.  
  198.     return bCreated;
  199. }
  200.  
  201. COleControlSite* COleControlContainer::FindItem(UINT nID) const
  202. {
  203.     POSITION pos = m_siteMap.GetStartPosition();
  204.     while (pos != NULL)
  205.     {
  206.         HWND hWnd;
  207.         COleControlSite* pSite;
  208.         m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  209.         if (pSite->GetID() == nID)
  210.             return pSite;
  211.     }
  212.     return NULL;
  213. }
  214.  
  215. BOOL COleControlContainer::GetAmbientProp(COleControlSite* pSite, DISPID dispid,
  216.     VARIANT* pvarResult)
  217. {
  218.     switch (dispid)
  219.     {
  220.     case DISPID_AMBIENT_AUTOCLIP:
  221.     case DISPID_AMBIENT_MESSAGEREFLECT:
  222.     case DISPID_AMBIENT_SUPPORTSMNEMONICS:
  223.     case DISPID_AMBIENT_USERMODE:
  224.         V_VT(pvarResult) = VT_BOOL;
  225.         V_BOOL(pvarResult) = (VARIANT_BOOL)-1;
  226.         return TRUE;
  227.  
  228.     case DISPID_AMBIENT_SHOWGRABHANDLES:
  229.     case DISPID_AMBIENT_SHOWHATCHING:
  230.     case DISPID_AMBIENT_UIDEAD:
  231.         V_VT(pvarResult) = VT_BOOL;
  232.         V_BOOL(pvarResult) = 0;
  233.         return TRUE;
  234.  
  235.     case DISPID_AMBIENT_APPEARANCE:     // ambient appearance is 3D
  236.         V_VT(pvarResult) = VT_I2;
  237.         if (afxData.bWin4)
  238. #ifndef _AFX_NO_CTL3D_SUPPORT
  239.         if (afxData.bWin4 || AfxGetCtl3dState()->m_pfnSubclassDlgEx != NULL)
  240. #else
  241.         if (afxData.bWin4)
  242. #endif
  243.             V_I2(pvarResult) = 1;
  244.         else
  245.             V_I2(pvarResult) = 0;
  246.         return TRUE;
  247.  
  248.     case DISPID_AMBIENT_BACKCOLOR:
  249.     case DISPID_AMBIENT_FORECOLOR:
  250.         if (m_crBack == (COLORREF)-1)   // ambient colors not initialized
  251.         {
  252.             CWindowDC dc(m_pWnd);
  253.             m_pWnd->SendMessage(WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC,
  254.                 (LPARAM)m_pWnd->m_hWnd);
  255.             m_crBack = dc.GetBkColor();
  256.             m_crFore = dc.GetTextColor();
  257.         }
  258.  
  259.         V_VT(pvarResult) = VT_COLOR;
  260.         V_I4(pvarResult) = (dispid == DISPID_AMBIENT_BACKCOLOR) ?
  261.             m_crBack : m_crFore;
  262.         return TRUE;
  263.  
  264.     case DISPID_AMBIENT_FONT:
  265.         if (m_pOleFont == NULL)         // ambient font not initialized
  266.             CreateOleFont(m_pWnd->GetFont());
  267.  
  268.         ASSERT(m_pOleFont != NULL);
  269.         if (m_pOleFont == NULL)         // failed to create font
  270.             return FALSE;
  271.  
  272.         V_VT(pvarResult) = VT_FONT;
  273.         m_pOleFont->AddRef();
  274.         V_DISPATCH(pvarResult) = m_pOleFont;
  275.         return TRUE;
  276.  
  277.     case DISPID_AMBIENT_DISPLAYASDEFAULT:
  278.         V_VT(pvarResult) = VT_BOOL;
  279.         V_BOOL(pvarResult) = (VARIANT_BOOL)(pSite->IsDefaultButton() ? -1 : 0);
  280.         return TRUE;
  281.  
  282.     case DISPID_AMBIENT_LOCALEID:
  283.         V_VT(pvarResult) = VT_I4;
  284. #if defined(_WIN32_WCE)
  285.         V_I4(pvarResult) = LOCALE_USER_DEFAULT;
  286. #else  // _WIN32_WCE
  287.         V_I4(pvarResult) = GetThreadLocale();
  288. #endif // _WIN32_WCE
  289.         return TRUE;
  290.  
  291.     case DISPID_AMBIENT_DISPLAYNAME:
  292.         {
  293.             CString str;                // return blank string
  294.             V_VT(pvarResult) = VT_BSTR;
  295.             V_BSTR(pvarResult) = str.AllocSysString();
  296.         }
  297.         return TRUE;
  298.  
  299.     case DISPID_AMBIENT_SCALEUNITS:
  300.         {
  301.             CString str;
  302.             str.LoadString(AFX_IDS_OCC_SCALEUNITS_PIXELS);
  303.             V_VT(pvarResult) = VT_BSTR;
  304.             V_BSTR(pvarResult) = str.AllocSysString();
  305.         }
  306.         return TRUE;
  307.     }
  308.  
  309.     return FALSE;
  310. }
  311.  
  312. void COleControlContainer::CreateOleFont(CFont* pFont)
  313. {
  314.     USES_CONVERSION;
  315.  
  316.     CFont fontSys;
  317.     if ((pFont == NULL) || (pFont->m_hObject == NULL))
  318.     {
  319.         // no font was provided, so use the system font
  320.         if (fontSys.CreateStockObject(DEFAULT_GUI_FONT) ||
  321.             fontSys.CreateStockObject(SYSTEM_FONT))
  322.         {
  323.             pFont = &fontSys;
  324.         }
  325.         else
  326.         {
  327.             m_pOleFont = NULL;
  328.             return;
  329.         }
  330.     }
  331.  
  332.     LOGFONT logfont;
  333.     pFont->GetLogFont(&logfont);
  334.  
  335.     FONTDESC fd;
  336.     fd.cbSizeofstruct = sizeof(FONTDESC);
  337.     fd.lpstrName = T2OLE(logfont.lfFaceName);
  338.     fd.sWeight = (short)logfont.lfWeight;
  339.     fd.sCharset = logfont.lfCharSet;
  340.     fd.fItalic = logfont.lfItalic;
  341.     fd.fUnderline = logfont.lfUnderline;
  342.     fd.fStrikethrough = logfont.lfStrikeOut;
  343.  
  344.     long lfHeight = logfont.lfHeight;
  345.     if (lfHeight < 0)
  346.         lfHeight = -lfHeight;
  347.  
  348.     CWindowDC dc(m_pWnd);
  349.     int ppi = dc.GetDeviceCaps(LOGPIXELSY);
  350.     fd.cySize.Lo = lfHeight * 720000 / ppi;
  351.     fd.cySize.Hi = 0;
  352.  
  353.     RELEASE(m_pOleFont);
  354.     if (FAILED(::WCE_FCTN(OleCreateFontIndirect)(&fd, IID_IFontDisp, (void**)&m_pOleFont)))
  355.         m_pOleFont = NULL;
  356. }
  357.  
  358. void COleControlContainer::FreezeAllEvents(BOOL bFreeze)
  359. {
  360.     HWND hWnd;
  361.     COleControlSite* pSite;
  362.     POSITION pos = m_siteMap.GetStartPosition();
  363.     while (pos != NULL)
  364.     {
  365.         m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  366.         pSite->FreezeEvents(bFreeze);
  367.     }
  368. }
  369.  
  370. void COleControlContainer::ScrollChildren(int dx, int dy)
  371. {
  372.     HWND hWnd;
  373.     COleControlSite* pSite;
  374.     POSITION pos = m_siteMap.GetStartPosition();
  375.     while (pos != NULL)
  376.     {
  377.         m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  378.         ASSERT(pSite->m_pInPlaceObject != NULL);
  379.         ASSERT(pSite->m_pObject != NULL);
  380.         pSite->m_rect.OffsetRect(dx, dy);
  381.         pSite->m_pInPlaceObject->SetObjectRects(pSite->m_rect, pSite->m_rect);
  382.     }
  383. }
  384.  
  385. void COleControlContainer::OnUIActivate(COleControlSite* pSite)
  386. {
  387.     if (m_pSiteUIActive != NULL)
  388.         m_pSiteUIActive->m_pInPlaceObject->UIDeactivate();
  389.  
  390.     ASSERT(m_pSiteUIActive == NULL);    // did control call OnUIDeactivate?
  391.     m_pSiteUIActive = pSite;
  392. }
  393.  
  394. void COleControlContainer::OnUIDeactivate(COleControlSite* pSite)
  395. {
  396.     UNUSED(pSite);
  397.  
  398.     if (m_pSiteUIActive == pSite)
  399.         m_pSiteUIActive = NULL;
  400. }
  401.  
  402. /////////////////////////////////////////////////////////////////////////////
  403. // special cases for CWnd functions
  404.  
  405. void COleControlContainer::CheckDlgButton(int nIDButton, UINT nCheck)
  406. {
  407.     CWnd* pWnd = GetDlgItem(nIDButton);
  408.     if (pWnd == NULL)
  409.         return;
  410.  
  411.     if (pWnd->m_pCtrlSite == NULL)
  412.     {
  413.         pWnd->SendMessage(BM_SETCHECK, nCheck, 0);
  414.         return;
  415.     }
  416.  
  417.     pWnd->m_pCtrlSite->SafeSetProperty(DISPID_VALUE, VT_I4, DISPATCH_PROPERTYPUT, (DWORD)nCheck);
  418. }
  419.  
  420. void COleControlContainer::CheckRadioButton(int nIDFirstButton, int nIDLastButton,
  421.     int nIDCheckButton)
  422. {
  423.     ASSERT(nIDFirstButton <= nIDCheckButton);
  424.     ASSERT(nIDCheckButton <= nIDLastButton);
  425.  
  426.     // the following code is for OLE control containers only
  427.     for (int nID = nIDFirstButton; nID <= nIDLastButton; nID++)
  428.         CheckDlgButton(nID, (nID == nIDCheckButton));
  429. }
  430.  
  431. CWnd* COleControlContainer::GetDlgItem(int nID) const
  432. {
  433.     HWND hWnd;
  434.     GetDlgItem(nID, &hWnd);
  435.     return CWnd::FromHandle(hWnd);
  436. }
  437.  
  438. void COleControlContainer::GetDlgItem(int nID, HWND* phWnd) const
  439. {
  440.     // first, look for a non-OLE control
  441.     HWND hWnd = ::GetDlgItem(m_pWnd->GetSafeHwnd(), nID);
  442.     if (hWnd == NULL)
  443.     {
  444.         // now, look for an OLE control
  445.         COleControlSite* pSite = FindItem(nID);
  446.         if (pSite != NULL)
  447.             hWnd = pSite->m_hWnd;
  448.     }
  449.  
  450.     *phWnd = hWnd;
  451. }
  452.  
  453. UINT COleControlContainer::GetDlgItemInt(int nID, BOOL* lpTrans, BOOL bSigned) const
  454. {
  455.     TCHAR szText[256];
  456.     if (GetDlgItemText(nID, szText, 256) == 0)
  457.     {
  458.         if (lpTrans != NULL)
  459.             *lpTrans = FALSE;
  460.         return 0;
  461.     }
  462.  
  463.     // Quick check for valid number
  464.     LPTSTR pch = szText;
  465.  
  466.     while (_istspace(*pch))
  467.         pch = CharNext(pch);    // skip whitespace
  468.  
  469.     if ((*pch) == '+' || (*pch) == '-')
  470.         pch = CharNext(pch);    // skip sign
  471.  
  472.     BOOL bTrans = _istdigit(*pch);    // did we find a digit?
  473.  
  474.     if (lpTrans != NULL)
  475.         *lpTrans = bTrans;
  476.  
  477.     if (!bTrans)
  478.         return 0;
  479.  
  480.     if (bSigned)
  481.         return _tcstol(szText, NULL, 10);
  482.     else
  483.         return _tcstoul(szText, NULL, 10);
  484. }
  485.  
  486. int COleControlContainer::GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount) const
  487. {
  488.     CWnd* pWnd = GetDlgItem(nID);
  489.     if (pWnd == NULL)
  490.         return 0;
  491.  
  492.     return pWnd->GetWindowText(lpStr, nMaxCount);
  493. }
  494.  
  495. LRESULT COleControlContainer::SendDlgItemMessage(int nID, UINT message, WPARAM wParam,
  496.     LPARAM lParam)
  497. {
  498.     CWnd* pWnd = GetDlgItem(nID);
  499.     if (pWnd == NULL)
  500.         return 0;
  501.  
  502.     return pWnd->SendMessage(message, wParam, lParam);
  503. }
  504.  
  505. void COleControlContainer::SetDlgItemInt(int nID, UINT nValue, BOOL bSigned)
  506. {
  507.     TCHAR szText[34];
  508.     if (bSigned)
  509.         _ltot((long)nValue, szText, 10);
  510.     else
  511.         _ultot((unsigned long)nValue, szText, 10);
  512.  
  513.     SetDlgItemText(nID, szText);
  514. }
  515.  
  516. void COleControlContainer::SetDlgItemText(int nID, LPCTSTR lpszString)
  517. {
  518.     CWnd* pWnd = GetDlgItem(nID);
  519.     if (pWnd == NULL)
  520.         return;
  521.  
  522.     pWnd->SetWindowText(lpszString);
  523. }
  524.  
  525. UINT COleControlContainer::IsDlgButtonChecked(int nIDButton) const
  526. {
  527.     CWnd* pWnd = GetDlgItem(nIDButton);
  528.     if (pWnd == NULL)
  529.         return 0;
  530.  
  531.     if (pWnd->m_pCtrlSite == NULL)
  532.         return pWnd->SendMessage(BM_GETCHECK, 0, 0);
  533.  
  534.     DWORD dwValue;
  535.  
  536.     TRY
  537.     {
  538.         pWnd->GetProperty(DISPID_VALUE, VT_I4, &dwValue);
  539.     }
  540.     CATCH_ALL(e)
  541.     {
  542.         DELETE_EXCEPTION(e);
  543.         dwValue = 0;
  544.     }
  545.     END_CATCH_ALL
  546.  
  547.     if (dwValue == 0x0000ffff)  // VARIANT_BOOL TRUE
  548.         dwValue = 1;
  549.  
  550.     return dwValue;
  551. }
  552.  
  553. /////////////////////////////////////////////////////////////////////////////
  554. // COleControlContainer::XOleIPFrame
  555.  
  556. STDMETHODIMP COleControlContainer::XOleIPFrame::QueryInterface(
  557.     REFIID iid, LPVOID* ppvObj)
  558. {
  559.     METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  560.     return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  561. }
  562.  
  563. STDMETHODIMP_(ULONG) COleControlContainer::XOleIPFrame::AddRef()
  564. {
  565.     METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  566.     return (ULONG)pThis->InternalAddRef();
  567. }
  568.  
  569. STDMETHODIMP_(ULONG) COleControlContainer::XOleIPFrame::Release()
  570. {
  571.     METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  572.     return (ULONG)pThis->InternalRelease();
  573. }
  574.  
  575. STDMETHODIMP COleControlContainer::XOleIPFrame::GetWindow(HWND* phWnd)
  576. {
  577.     METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  578.  
  579.     *phWnd = pThis->m_pWnd->m_hWnd;
  580.     return S_OK;
  581. }
  582.  
  583. STDMETHODIMP COleControlContainer::XOleIPFrame::ContextSensitiveHelp(BOOL)
  584. {
  585.     return E_NOTIMPL;
  586. }
  587.  
  588. STDMETHODIMP COleControlContainer::XOleIPFrame::GetBorder(LPRECT)
  589. {
  590.     return E_NOTIMPL;
  591. }
  592.  
  593. STDMETHODIMP COleControlContainer::XOleIPFrame::RequestBorderSpace(
  594.     LPCBORDERWIDTHS)
  595. {
  596.     return E_NOTIMPL;
  597. }
  598.  
  599. STDMETHODIMP COleControlContainer::XOleIPFrame::SetBorderSpace(
  600.     LPCBORDERWIDTHS)
  601. {
  602.     return E_NOTIMPL;
  603. }
  604.  
  605. STDMETHODIMP COleControlContainer::XOleIPFrame::SetActiveObject(
  606.     LPOLEINPLACEACTIVEOBJECT pActiveObject, LPCOLESTR)
  607. {
  608.     METHOD_PROLOGUE_EX_(COleControlContainer, OleIPFrame)
  609.  
  610.     if (pThis->m_pSiteUIActive != NULL)
  611.     {
  612.         LPOLEINPLACEACTIVEOBJECT pOldActiveObject = pThis->m_pSiteUIActive->m_pActiveObject;
  613.         if (pActiveObject != NULL)
  614.             pActiveObject->AddRef();
  615.         pThis->m_pSiteUIActive->m_pActiveObject = pActiveObject;
  616.         if (pOldActiveObject != NULL)
  617.             pOldActiveObject->Release();
  618.     }
  619.     return S_OK;
  620. }
  621.  
  622. STDMETHODIMP COleControlContainer::XOleIPFrame::InsertMenus(HMENU,
  623.     LPOLEMENUGROUPWIDTHS)
  624. {
  625.     return E_NOTIMPL;
  626. }
  627.  
  628. STDMETHODIMP COleControlContainer::XOleIPFrame::SetMenu(HMENU, HOLEMENU, HWND)
  629. {
  630.     return E_NOTIMPL;
  631. }
  632.  
  633. STDMETHODIMP COleControlContainer::XOleIPFrame::RemoveMenus(HMENU)
  634. {
  635.     return E_NOTIMPL;
  636. }
  637.  
  638. STDMETHODIMP COleControlContainer::XOleIPFrame::SetStatusText(LPCOLESTR)
  639. {
  640.     return E_NOTIMPL;
  641. }
  642.  
  643. STDMETHODIMP COleControlContainer::XOleIPFrame::EnableModeless(BOOL)
  644. {
  645.    // As long as we don't create any modeless dialogs, we can just return S_OK.
  646.     return S_OK;
  647. }
  648.  
  649. STDMETHODIMP COleControlContainer::XOleIPFrame::TranslateAccelerator(LPMSG,
  650.     WORD)
  651. {
  652.     return E_NOTIMPL;
  653. }
  654.  
  655. /////////////////////////////////////////////////////////////////////////////
  656. // CEnumUnknown - enumerator for IUnknown pointers
  657.  
  658. class CEnumUnknown : public CEnumArray
  659. {
  660. public:
  661.     CEnumUnknown(const void* pvEnum, UINT nSize) :
  662.         CEnumArray(sizeof(LPUNKNOWN), pvEnum, nSize, TRUE) {}
  663.     ~CEnumUnknown();
  664.  
  665. protected:
  666.     virtual BOOL OnNext(void* pv);
  667.  
  668.     DECLARE_INTERFACE_MAP()
  669. };
  670.  
  671. BEGIN_INTERFACE_MAP(CEnumUnknown, CEnumArray)
  672.     INTERFACE_PART(CEnumUnknown, IID_IEnumUnknown, EnumVOID)
  673. END_INTERFACE_MAP()
  674.  
  675. CEnumUnknown::~CEnumUnknown()
  676. {
  677.     if (m_pClonedFrom == NULL)
  678.     {
  679.         LPUNKNOWN* ppUnk = (LPUNKNOWN*)(void*)m_pvEnum;
  680.         for (UINT i = 0; i < m_nSize; i++)
  681.         {
  682.             ASSERT(ppUnk[i] != NULL);
  683.             ppUnk[i]->Release();
  684.         }
  685.     }
  686.     // destructor will free the actual array (if it was not a clone)
  687. }
  688.  
  689. BOOL CEnumUnknown::OnNext(void* pv)
  690. {
  691.     if (!CEnumArray::OnNext(pv))
  692.         return FALSE;
  693.  
  694.     // AddRef the pointer (the caller has responsibility to Release it)
  695.     ASSERT(*(LPUNKNOWN*)pv != NULL);
  696.     (*(LPUNKNOWN*)pv)->AddRef();
  697.  
  698.     return TRUE;
  699. }
  700.  
  701. /////////////////////////////////////////////////////////////////////////////
  702. // COleControlContainer::XOleContainer
  703.  
  704. STDMETHODIMP COleControlContainer::XOleContainer::QueryInterface(
  705.     REFIID iid, LPVOID* ppvObj)
  706. {
  707.     METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  708.     return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  709. }
  710.  
  711. STDMETHODIMP_(ULONG) COleControlContainer::XOleContainer::Release()
  712. {
  713.     METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  714.     return (ULONG)pThis->InternalRelease();
  715. }
  716.  
  717. STDMETHODIMP_(ULONG) COleControlContainer::XOleContainer::AddRef()
  718. {
  719.     METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  720.     return (ULONG)pThis->InternalAddRef();
  721. }
  722.  
  723. STDMETHODIMP COleControlContainer::XOleContainer::ParseDisplayName(LPBINDCTX,
  724.     LPOLESTR, ULONG*, LPMONIKER*)
  725. {
  726.     return E_NOTIMPL;
  727. }
  728.  
  729. STDMETHODIMP COleControlContainer::XOleContainer::EnumObjects(DWORD dwFlags,
  730.     LPENUMUNKNOWN* ppEnumUnknown)
  731. {
  732.     METHOD_PROLOGUE_EX_(COleControlContainer, OleContainer)
  733.  
  734.     *ppEnumUnknown = NULL;
  735.     HRESULT hr = S_OK;
  736.     CEnumUnknown* pEnum = NULL;
  737.     UINT cObjects = 0;
  738.     LPUNKNOWN* ppUnk = NULL;
  739.  
  740.     TRY
  741.     {
  742.         if (dwFlags & OLECONTF_EMBEDDINGS)
  743.         {
  744.             cObjects = pThis->m_siteMap.GetCount();
  745.             ppUnk = new LPUNKNOWN[cObjects];
  746.             UINT i = 0;
  747.             POSITION pos = pThis->m_siteMap.GetStartPosition();
  748.             HWND hWnd;
  749.             COleControlSite* pSite;
  750.             while (pos != NULL)
  751.             {
  752.                 pThis->m_siteMap.GetNextAssoc(pos, (void*&)hWnd, (void*&)pSite);
  753.                 ASSERT(pSite->m_pObject != NULL);
  754.                 pSite->m_pObject->AddRef();
  755.                 ppUnk[i++] = pSite->m_pObject;
  756.             }
  757.  
  758.             ASSERT(cObjects == i);
  759.         }
  760.         pEnum = new CEnumUnknown(ppUnk, cObjects);
  761.     }
  762.     CATCH_ALL(e)
  763.     {
  764.         // Note: DELETE_EXCEPTION(e) not necessary
  765.         hr = E_OUTOFMEMORY;
  766.     }
  767.     END_CATCH_ALL
  768.  
  769.     // clean up in case of failure
  770.     if (SUCCEEDED(hr))
  771.     {
  772.         ASSERT(pEnum != NULL);
  773.         *ppEnumUnknown = (IEnumUnknown*)&pEnum->m_xEnumVOID;
  774.     }
  775.     else
  776.     {
  777.         ASSERT(pEnum == NULL);
  778.         ASSERT(*ppEnumUnknown == NULL);
  779.  
  780.         if (ppUnk != NULL)
  781.         {
  782.             for (UINT i = 0; i < cObjects; i++)
  783.             {
  784.                 ASSERT(ppUnk[i] != NULL);
  785.                 ppUnk[i]->Release();
  786.             }
  787.         }
  788.     }
  789.  
  790.     return hr;
  791. }
  792.  
  793. STDMETHODIMP COleControlContainer::XOleContainer::LockContainer(BOOL)
  794. {
  795.     return E_NOTIMPL;
  796. }
  797.